/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PanLabeling.java
 *
 * Created on 01-ago-2011, 23:37:49
 */

package br.usp.ime.faguilar.guis;

import DatabaseMathExpressions.DBFuntions;
import DatabaseMathExpressions.ModelExpression;
import DatabaseMathExpressions.UserExpression;
import MathExpression.Graphics.GMathExpression;
import Util.Scale;
import Util.Util;
import br.usp.ime.faguilar.guis.matching.PanMatching;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

/**
 *
 * @author frank
 */
public class PanLabeling extends javax.swing.JPanel {
    protected ModelExpression selectedME;

    protected UserExpression selectedUE;

    ArrayList<UserExpression> alue;
    private ComboBoxRenderer renderer;

    protected DBFuntions dbFunctions;

    private ArrayList<ModelExpression> alME;

    private int posSelectedUserExpression;

    private boolean showEvaluatedExpressions;

    private static final int preferedWidthOfLateralPanel=294;
    
    private static final Point modelIDPosition=new Point(JListHandler.MAX_WIDTH_OF_IMAGES/2-10,JListHandler.MAX_HEIGHT_OF_IMAGES+25);

    /** Creates new form PanLabeling */
    public PanLabeling() {
        initComponents();
        selectedME=null;
        selectedUE=null;
        posSelectedUserExpression=-1;
        this.panControlOfMatchingPanel.getPanMatching().setPanManagerOfUserExpression(this);
        this.panControlOfMatchingPanel.enableControlls(false);
        showEvaluatedExpressions=false;

    }

    public DBFuntions getDbFunctions() {
        return dbFunctions;
    }

    public void setDbFunctions(DBFuntions dbFunctions) {
        this.dbFunctions = dbFunctions;
    }


    public void chargeModelsJList(){      
        ArrayList<ModelExpression> alModelExpressionsToCharge=null;//=dbFunctions.getModelExpressions();
        alModelExpressionsToCharge=dbFunctions.getModelsByEvaluated(showEvaluatedExpressions);

        alME=alModelExpressionsToCharge;
        for (ModelExpression modelExpression : alModelExpressionsToCharge) {
            ((GMathExpression)modelExpression.getdMathExpression()).showJustMathExpression();
        }
        this.updateJListOfModels();
    }

    private void deleteSelectedModel(){
        this.alME.remove(selectedME);
        this.updateJListOfModels();
    }

    private void updateJListOfModels(){
        this.jListModels=new JList(Util.toObjectArray(alME));
        jListModels.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListModelsValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jListModels);
        renderer= new ComboBoxRenderer();
        renderer.setPreferredSize(new Dimension(JListHandler.MAX_WIDTH_OF_IMAGES+20
                , JListHandler.MAX_HEIGHT_OF_IMAGES+30));
        jListModels.setCellRenderer(renderer);
        jListModels.repaint();
    }

    public void chargeUserExpressionsJList(){
        if(this.selectedME!=null){
            alue=dbFunctions.getUserExpressionsForModel(selectedME.getId(),this.showEvaluatedExpressions);

            jListUserExpressions=new JList(Util.toObjectArray(alue));

            jListUserExpressions.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
                public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                    jListUserExpressionsValueChanged(evt);
                }
            });
            jScrollPane2.setViewportView(jListUserExpressions);
            jListUserExpressions.repaint();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        panControlOfMatchingPanel = new br.usp.ime.faguilar.guis.matching.PanControlOfMatchingPanel();
        jSplitPane2 = new javax.swing.JSplitPane();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jListModels = new javax.swing.JList();
        jPanel5 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jListUserExpressions = new javax.swing.JList();
        jPanel6 = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        butShowAllOrUnevaluated = new javax.swing.JButton();

        setLayout(new java.awt.BorderLayout());

        jSplitPane1.setDividerLocation(300);

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 0, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 0, Short.MAX_VALUE)
        );

        jSplitPane1.setLeftComponent(jPanel1);

        jPanel2.setLayout(new java.awt.BorderLayout());
        jPanel2.add(panControlOfMatchingPanel, java.awt.BorderLayout.CENTER);

        jSplitPane1.setRightComponent(jPanel2);

        jSplitPane2.setDividerLocation(400);
        jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Model expressions"));
        jPanel3.setLayout(new java.awt.BorderLayout());

        jListModels.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListModelsValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jListModels);

        jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel5.setLayout(new java.awt.BorderLayout());
        jPanel3.add(jPanel5, java.awt.BorderLayout.PAGE_START);

        jSplitPane2.setTopComponent(jPanel3);

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Database expressions"));
        jPanel4.setLayout(new java.awt.BorderLayout());

        jListUserExpressions.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListUserExpressionsValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(jListUserExpressions);

        jPanel4.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        jPanel6.setLayout(new java.awt.BorderLayout());
        jPanel4.add(jPanel6, java.awt.BorderLayout.PAGE_END);

        jSplitPane2.setRightComponent(jPanel4);

        jSplitPane1.setLeftComponent(jSplitPane2);

        add(jSplitPane1, java.awt.BorderLayout.CENTER);

        jButton1.setText("Hide");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        butShowAllOrUnevaluated.setText("Evaluated expressions");
        butShowAllOrUnevaluated.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butShowAllOrUnevaluatedMouseClicked(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel7Layout = new org.jdesktop.layout.GroupLayout(jPanel7);
        jPanel7.setLayout(jPanel7Layout);
        jPanel7Layout.setHorizontalGroup(
            jPanel7Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel7Layout.createSequentialGroup()
                .add(jButton1)
                .add(26, 26, 26)
                .add(butShowAllOrUnevaluated, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 189, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(910, Short.MAX_VALUE))
        );
        jPanel7Layout.setVerticalGroup(
            jPanel7Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel7Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                .add(jButton1)
                .add(butShowAllOrUnevaluated))
        );

        add(jPanel7, java.awt.BorderLayout.PAGE_START);
    }// </editor-fold>//GEN-END:initComponents

    public boolean isShowEvaluatedExpressions() {
        return showEvaluatedExpressions;
    }

    public void setShowEvaluatedExpressions(boolean showAllExpressions) {
        this.showEvaluatedExpressions = showAllExpressions;
    }


    private void jListModelsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListModelsValueChanged
        // TODO add your handling code here:
        int pos= jListModels.getSelectedIndex();
        if(pos>=0){
            selectedME=(ModelExpression) jListModels.getModel().getElementAt(pos);//db.getAlModelExpression().get(pos); //(ModelExpression) jListModels.getModel().getElementAt(pos);//
            //alue=selectedME.getAlUserExpression();
//            JListHandler.chargeListOfUserExpressions( alue, jListUserExpressions);
            this.chargeUserExpressionsJList();
            this.panControlOfMatchingPanel.getPanMatching().clearPanel();
            this.panControlOfMatchingPanel.getPanMatching().setTypeOfDrawing(PanMatching.TYPE_DRAWING_JUST_MODEL_EXPR);
            panControlOfMatchingPanel.getPanMatching().setgMathExpressionModel((GMathExpression) selectedME.getdMathExpression());
            panControlOfMatchingPanel.getPanMatching().repaint();
            this.panControlOfMatchingPanel.enableControlls(false);
        }
    }//GEN-LAST:event_jListModelsValueChanged

    private void jListUserExpressionsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListUserExpressionsValueChanged
        // TODO add your handling code here:
        if(!evt.getValueIsAdjusting()){
            int pos= jListUserExpressions.getSelectedIndex();
            if(pos>=0){
                selectUserExpression(pos);
            }
        }
}//GEN-LAST:event_jListUserExpressionsValueChanged

    private void selectUserExpression(int pos){
        selectedUE=alue.get(pos); //(UserExpression) jListUserExpressions.getModel().getElementAt(pos);//alue.get(pos);//(UserExpression) jListUserExpressions.getModel().getElementAt(pos);//alue.get(pos);
            posSelectedUserExpression=pos;
            this.showMatching();
            this.panControlOfMatchingPanel.enableControlls(true);
            this.panControlOfMatchingPanel.getPanMatching().setTypeOfDrawing(PanMatching.TYPE_DRAWING_JUST_MATCHING);
            this.panControlOfMatchingPanel.setEvaluatedExpressionInChBox(selectedUE.isEvaluated());
//            System.out.println("Matching for model "+ selectedME.getId()
//                    +" and instance of "+selectedUE.getIdUser());
//            Util.printMatrix(selectedUE.getMatch());
    }

    public void updateMatching(int[][] matching){
        selectedUE.setMatch(matching);
        this.dbFunctions.setMatchingUserExpression(selectedUE.getId(), matching);
    }

    public int[][] getMatchingMatrix(){
        return selectedUE.getMatch();
    }

    public void saveEvaluatedExpression(){
        if(selectedUE!=null){
            boolean evaluated=true;
            dbFunctions.setEvaluateUserExpression(selectedUE.getId(), evaluated);
            this.chargeUserExpressionsJList();
            int numUserExpressions=this.jListUserExpressions.getModel().getSize();
            this.panControlOfMatchingPanel.getPanMatching().clearPanel();
            if(numUserExpressions>0){
                this.panControlOfMatchingPanel.getPanMatching().setTypeOfDrawing(PanMatching.TYPE_DRAWING_JUST_MODEL_EXPR);
                panControlOfMatchingPanel.getPanMatching().setgMathExpressionModel((GMathExpression) selectedME.getdMathExpression());
                panControlOfMatchingPanel.repaint();
                if(posSelectedUserExpression>=numUserExpressions){
                    posSelectedUserExpression=numUserExpressions-1;
                }
                this.jListUserExpressions.setSelectedIndex(posSelectedUserExpression);
            }else{
                this.deleteSelectedModel();
            }
//            this.panControlOfMatchingPanel.enableControlls(false);
        }
    }

    public ModelExpression getSelectedME() {
        return selectedME;
    }

    public UserExpression getSelectedUE() {
        return selectedUE;
    }



    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseClicked
        // TODO add your handling code here:
        if(this.jButton1.getText().equals("Hide")){
            this.jSplitPane1.setDividerLocation(2);
            jButton1.setText("Show");
        }
        else{
            this.jSplitPane1.setDividerLocation(preferedWidthOfLateralPanel);
            jButton1.setText("Hide");
        }
    }//GEN-LAST:event_jButton1MouseClicked

    private void butShowAllOrUnevaluatedMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butShowAllOrUnevaluatedMouseClicked
        // TODO add your handling code here:
        if(this.isShowEvaluatedExpressions()){
            //then shows unevaluated expressions
            this.setShowEvaluatedExpressions(false);
            this.butShowAllOrUnevaluated.setText("Evaluated expressions");
            this.chargeModelsJList();
            this.chargeUserExpressionsJList();
        }else{
            this.setShowEvaluatedExpressions(true);
            this.butShowAllOrUnevaluated.setText("Unevaluated Expressions");
            this.chargeModelsJList();
            this.chargeUserExpressionsJList();
        }
    }//GEN-LAST:event_butShowAllOrUnevaluatedMouseClicked

    public void showMatching(){
        panControlOfMatchingPanel.getPanMatching().setgMathExpressionInput((GMathExpression) selectedUE.getdMExpression());
       // panControlOfMatchingPanel.setgMathExpressionModel((GMathExpression) selectedME.getdMathExpression());
        panControlOfMatchingPanel.getPanMatching().setMatch(selectedUE.getMatch());
        panControlOfMatchingPanel.setUpMatchingDrawer();
        panControlOfMatchingPanel.repaint();
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton butShowAllOrUnevaluated;
    private javax.swing.JButton jButton1;
    private javax.swing.JList jListModels;
    private javax.swing.JList jListUserExpressions;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private br.usp.ime.faguilar.guis.matching.PanControlOfMatchingPanel panControlOfMatchingPanel;
    // End of variables declaration//GEN-END:variables

    class ComboBoxRenderer extends JLabel
                           implements ListCellRenderer {
        private Font uhOhFont;

        private ModelExpression modelExpression;
        private final Point2D initOfGMathExpression=new Point2D.Double(); 
        public ComboBoxRenderer() {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
//            setVerticalTextPosition(JLabel.TOP);
//            this.setHorizontalTextPosition(LEFT);
            
            modelExpression=null;
        }

        public ModelExpression getModelExpression() {
            return modelExpression;
        }

        public void setAndLocateModelExpression(ModelExpression modelExpression) {
            this.modelExpression = modelExpression;
            locateModelExpression();
        }
        
        public void locateModelExpression(){
            Scale scale=Scale.ScaleFromDimensions(modelExpression.getdMathExpression().getBBox().getSize(),
                    new Dimension(JListHandler.MAX_WIDTH_OF_IMAGES,
                    JListHandler.MAX_HEIGHT_OF_IMAGES));
            scale.scale();
            Point2D location=scale.calculateScaledCentralPosition();
            Point2D translation=new Point2D.Double(location.getX()-modelExpression.getdMathExpression().getLtPoint().getX(),
                    location.getY()-modelExpression.getdMathExpression().getLtPoint().getY());
            ((GMathExpression)modelExpression.getdMathExpression()).translate(translation.getX(),translation.getY());
        }
        @Override
        public void paint(Graphics g){
           super.paint(g);
           Graphics2D g2D=(Graphics2D)g;
           
           if(modelExpression!=null){
//               Color c=g.getColor();
//               g.setColor(Color.BLACK);
               g.drawString("Model "+modelExpression.getId(),modelIDPosition.x,modelIDPosition.y);
               Scale scale=Scale.ScaleFromDimensions(modelExpression.getdMathExpression().getBBox().getSize(),
                   new Dimension(JListHandler.MAX_WIDTH_OF_IMAGES,
                    JListHandler.MAX_HEIGHT_OF_IMAGES));
               scale.scale();
                g2D.scale(scale.getHorizontalScale(),scale.getVerticalScale());
               ((GMathExpression)modelExpression.getdMathExpression()).drawGMathExpression(g);
               
//               g.setColor(c);
           }
        }

        /*
         * This method finds the image and text corresponding
         * to the selected value and returns the label, set up
         * to display the text and image.
         */
        public Component getListCellRendererComponent(
                                           JList list,
                                           Object value,
                                           int index,
                                           boolean isSelected,
                                           boolean cellHasFocus) {
            if (isSelected) {
                setBackground(list.getSelectionBackground());
//                setPreferredSize(new Dimension(getSize().width, getSize().height+20));
                setForeground(list.getSelectionForeground());

            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
       
            ArrayList<ModelExpression> models=alME;//db.getAlModelExpression();
            //Set the icon and text.  If icon was null, say so.
//            modelExpression=((ModelExpression)value);//models.get(index);
            this.setAndLocateModelExpression(((ModelExpression)value));
//            setIcon(new ImageIcon(UtilForGraphics.scaleImage(icon.getImage(),new Rectangle(JListHandler.MAX_WIDTH_OF_IMAGES,
//                    JListHandler.MAX_HEIGHT_OF_IMAGES))));
            String model = "Model "+models.get(index).getId();
            if (value != null) {
                setFont(list.getFont());
            }
            return this;
        }
    }
}
